package cn.cyxcoder.demo.producer;

import cn.cyxcoder.demo.config.RocketMQConfig;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.client.producer.TransactionMQProducer;
import org.apache.rocketmq.common.message.Message;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.nio.charset.StandardCharsets;

@Slf4j
@Component
public class MessageProducer {

    @Autowired
    private TransactionListenerImpl transactionListener;

    @Autowired
    private RocketMQConfig rocketMQConfig;

    private DefaultMQProducer producer;
    private TransactionMQProducer transactionProducer;

    private static final String TOPIC = "demo-topic";
    private static final String ORDER_TOPIC = "demo-order-topic";
    private static final String TRANSACTION_TOPIC = "demo-transaction-topic";

    @PostConstruct
    public void init() {
        // 初始化普通消息生产者
        producer = new DefaultMQProducer(rocketMQConfig.getProducer().getGroup());
        producer.setNamesrvAddr(rocketMQConfig.getNameServer());
        try {
            producer.start();
        } catch (Exception e) {
            log.error("普通消息生产者启动失败", e);
        }

        // 初始化事务消息生产者
        transactionProducer = new TransactionMQProducer("transaction-producer-group");
        transactionProducer.setNamesrvAddr(rocketMQConfig.getNameServer());
        transactionProducer.setTransactionListener(transactionListener);
        try {
            transactionProducer.start();
        } catch (Exception e) {
            log.error("事务消息生产者启动失败", e);
        }
    }

    @PreDestroy
    public void destroy() {
        if (producer != null) {
            producer.shutdown();
        }
        if (transactionProducer != null) {
            transactionProducer.shutdown();
        }
    }

    /**
     * 发送普通消息
     */
    public void sendNormalMessage(String message) {
        try {
            Message msg = new Message(TOPIC, message.getBytes(StandardCharsets.UTF_8));
            SendResult sendResult = producer.send(msg);
            log.info("发送普通消息成功: {}, 发送结果: {}", message, sendResult);
        } catch (Exception e) {
            log.error("发送普通消息失败", e);
        }
    }

    /**
     * 发送定时消息
     */
    public void sendDelayMessage(String message, int delayLevel) {
        try {
            Message msg = new Message(TOPIC, message.getBytes(StandardCharsets.UTF_8));
            msg.setDelayTimeLevel(delayLevel);
            SendResult sendResult = producer.send(msg);
            log.info("发送定时消息成功: {}, 延迟级别: {}, 发送结果: {}", message, delayLevel, sendResult);
        } catch (Exception e) {
            log.error("发送定时消息失败", e);
        }
    }

    /**
     * 发送顺序消息
     */
    public void sendOrderMessage(String message, String orderId) {
        try {
            Message msg = new Message(ORDER_TOPIC, message.getBytes(StandardCharsets.UTF_8));
            SendResult sendResult = producer.send(msg, (mqs, msg1, arg) -> {
                int index = Math.abs(arg.hashCode()) % mqs.size();
                return mqs.get(index);
            }, orderId);
            log.info("发送顺序消息成功: {}, 订单ID: {}, 发送结果: {}", message, orderId, sendResult);
        } catch (Exception e) {
            log.error("发送顺序消息失败", e);
        }
    }

    /**
     * 发送事务消息
     */
    public void sendTransactionMessage(String message) {
        try {
            Message msg = new Message(TRANSACTION_TOPIC, 
                "transaction-tag", 
                message.getBytes(StandardCharsets.UTF_8));
            SendResult sendResult = transactionProducer.sendMessageInTransaction(msg, null);
            log.info("发送事务消息成功: {}, 发送结果: {}", message, sendResult);
        } catch (Exception e) {
            log.error("发送事务消息失败", e);
        }
    }
} 